﻿package org.nickro.project.sound{
    import flash.display.*;
    import flash.media.SoundChannel;
	import flash.media.SoundTransform;
    import flash.media.Sound;
	
	import org.nickro.project.utils.Objects;
	import org.nickro.externallibrary.tween.TweenMax;
    public class SoundChan {

        private var pVolumeTween:TweenMax;
        
        var pSoundDef:SoundDef;
        public var pChannel:SoundChannel;
		var pTransform:SoundTransform;
        var pSound:Sound;

        public static const NO_VALUE:int = -2;

        public function SoundChan(oSound:Sound, oSoundDef:SoundDef){
            super();
            pSound = oSound;
            pSoundDef = oSoundDef;
            pTransform = new SoundTransform(oSoundDef.pVolume, oSoundDef.pPan);
            if (oSoundDef.pCrossover != 0){
                setCrossover(oSoundDef.pCrossover);
            };
        }
        public function loop(loops:int=0, volume:Number=-2, pan:Number=-2, start:Number=0):SoundChan{
            if (volume != NO_VALUE){
                pTransform.volume = volume;
            };
            if (pan != NO_VALUE){
                pTransform.pan = pan;
            };
            pChannel = pSound.play(start, loops, pTransform);
            return (this);
        }
        public function infiniteLoop(volume:Number=-2, pan:Number=-2, start:Number=0):SoundChan{
            if (volume != NO_VALUE){
                pTransform.volume = volume;
            };
            if (pan != NO_VALUE){
                pTransform.pan = pan;
            };
            pChannel = pSound.play(start, int.MAX_VALUE, pTransform);
            return (this);
        }
        public function stop():void{
            pChannel.stop();
        }
        private function fadeVolumeUpdate():void{
            pTransform = pChannel.soundTransform;
        }
        private function fadeVolumeComplete():void{
            pTransform = pChannel.soundTransform;
            pVolumeTween = null;
        }
        public function setCrossover(crossover:Number):void{
            var original:Number = (1 - crossover);
            pTransform.leftToLeft = original;
            pTransform.rightToRight = original;
            pTransform.leftToRight = crossover;
            pTransform.rightToLeft = crossover;
            if ((pChannel is SoundChannel)){
                pChannel.soundTransform = pTransform;
            };
        }
        public function play(volume:Number=-2, pan:Number=-2, start:Number=0):SoundChan{
            if (volume != NO_VALUE){
                pTransform.volume = volume;
            };
            if (pan != NO_VALUE){
                pTransform.pan = pan;
            };
            pChannel = pSound.play(start, 0, pTransform);
            return (this);
        }
        public function fadeVolume(fromVolume:Number=-2, toVolume:Number=0, seconds:Number=1, ease:Function=null):void{
            if (fromVolume == NO_VALUE){
                fromVolume = pTransform.volume;
            };
            if (!(ease is Function)){
                ease = Regular.easeInOut;
            };
            setVolume(fromVolume);
            pVolumeTween = TweenMax.to(pChannel, seconds, {volume:toVolume, ease:ease, onUpdate:fadeVolumeUpdate, onComplete:fadeVolumeComplete});
        }
        public function get transform():SoundTransform{
            return (pTransform);
        }
        public function setVolume(volume:Number):void{
            if ((pVolumeTween is TweenMax)){
                TweenMax.removeTween(pVolumeTween);
                pVolumeTween = null;
            };
            pTransform.volume = Math.max(0, Math.min(volume, 1));
            pChannel.soundTransform = pTransform;
        }
        public function isFadingVolume():Boolean{
            return ((pVolumeTween is TweenMax));
        }

        public static function createEmbeddedFromSoundDef(oSoundDef:SoundDef, containerSWF:Sprite=null):SoundChan{
            var oSound:Sound = Objects.instanceOfClass(oSoundDef.pName, containerSWF);
            return (new SoundChan(oSound, oSoundDef));
        }
        public static function createEmbedded(className:String, containerSWF:Sprite=null, volume:Number=1, pan:Number=0, crossover:Number=0):SoundChan{
            var oSound:Sound = Objects.instanceOfClass(className, containerSWF);
            var oSoundDef:SoundDef = new SoundDef(className, volume, pan, crossover);
            return (new SoundChan(oSound, oSoundDef));
        }

    }
}//package com.tobyfreeman.sound 
